/***************************************************************************
 创建者: 华磊
 开始时间: 2018.8.14
 copyright: (C) 华友高科
 修改说明: (每次有修改就添加一条，带有 修改人，修改时间，修改描述)
 example (1) hualei 2017.5.8 类的具体实现代码编写

 ***************************************************************************
 *  @file x.h
 *  功能:
 *
 *                                                                         *
 ***************************************************************************/
#ifndef PROGRAMENGINE_H
#define PROGRAMENGINE_H

#include "programengine_global.h"

#include <QStack>
#include <QThread>
#include <QObject>
#include <QCoreApplication>
#include <QQueue>
#include "GeneralDefine.h"
//#include "../../hmiAPI_update20161118.h"
#include "programset.h"
#include "../PointData/pointdata.h"
#include "../RegData/regdata.h"
#include "programupdatedata.h"
#include "../Md5Check/md5check.h"
#include "domparser.h"
#include "rsrinfo.h"
//#include "filedata.h"
#include "../ProgramLanguageTranslate/programlanguagetranslate.h"
#include "fleetdefine.h"

#define TEST_TIME_DEBUG 1

#define NSEC_PER_SEC    1000000000

class RobotIo;
class TaskManager;
//class PointData;
//class RegData;
//class Md5Check;
class McControllerThread;

class AbortInstructionLogic;
class CallInstructionLogic;
class CoordinateInstructionLogic;
class EndInstructionLogic;
class ErrorInstructionLogic;
class ForInstructionLogic;
class GoToInstructionLogic;
class GripperInstructionLogic;
class IfInstructionLogic;
class IoInstructionLogic;
class JumpInstructionLogic;
class LabelInstructionLogic;
class MessageInstructionLogic;
class MotionInstructionLogic;
class OverrideInstructionLogic;
class PalInstructionLogic;
class PauseInstructionLogic;
class RegInstructionLogic;
class RsrInstructionLogic;
class RunInstructionLogic;
class SelectInstructionLogic;
class TimerInstructionLogic;
class UalmInstructionLogic;
class WaitInstructionLogic;
class MoveMagneticInstructionLogic;
class MoveFreeInstructionLogic;
class MusicInstructionLogic;
class ChargingInstructionLogic;
class LiftMechanismInstructionLogic;
class TcpStartInstructionLogic;
class TcpReadInstructionLogic;
class TcpWriteInstructionLogic;
class LoadMapInstructionLogic;
class SetOdomInstructionLogic;
class CheckBatteryInstructionLogic;
class WaitCommandInstructionLogic;
class RobotMoveInstructionLogic;
class RollerInstructionLogic;
class ModbusStartInstructionLogic;
class ModbusReadInstructionLogic;
class ModbusWriteInstructionLogic;
class VisionRunLogic;
class TrackStartLogic;
//拓展新指令Fundation增加代码20191122hualei
class WeldStartInstructionLogic;
class WeldEndInstructionLogic;
class WeaveInstructionLogic;
class WeaveEndInstructionLogic;
class TrackWeldTastInstructionLogic;
class TrackWeldEndInstructionLogic;
class WatchDIInstructionLogic;
class LaserCameraAdapter;
class LaserCameraInstructionLogic;
class LaserCameraTrajServer;
/**
 * @brief The ProgramEngine class 程式解释引擎
 */
class PROGRAMENGINE_EXPORT ProgramEngine : public QObject, public DomParser
{
    Q_OBJECT
public:
    //for main task
     explicit ProgramEngine(int id,  RobotIo* ioControllerIn, RegData *mainRegDataIn, RsrInfo *tmpRsrInfo,int robotEngineStartTypeIn,
                            McControllerThread *proMcControllerThreadIn,QObject *parent = 0);
    //for child task
    explicit ProgramEngine(int id, RobotIo* ioControllerIn, RegData *mainRegData, RsrInfo *tmpRsrInfo
                           , TaskManager *taskManagerIn,
                           QThread* threadIn, int thisTaskIndex,QObject *parent = 0);

    ~ProgramEngine();



public:
    int startLaserScanBuffer();
    int stopLaserScanBuffer();
    int getLaserScanTraj(QVector<PointPro> refOri, QVector<PointPro> &keyPointsOut);
    int get_All_IO_NamesInfo( struct IOMapNamesInfo &nameOut);
    int set_IO_NameInfo( int IOValueTypeIn, int logicValueIndexIn, std::string nameIn, int &returnFlag);
    int getPalletConditionInfo(std::vector<struct PalletMiddleInfo> &infoOut);
    int setPalletConditionInfo(struct StackInfo infoIn);
    int getWeaveMotionConditionInfo(std::vector<struct WeaveMotionCondition> &infoOut);
    int setWeaveMotionConditionInfo(struct WeaveMotionCondition infoIn);
    E_PROGRAM_LOOP_RESULT fetchWeldPoint(PointPro &tcpPositionOut, int waitCountIn);
    bool getLaserCameraTrackStatus();
    int getWeldDebugStatusInfo(struct WeldCraftStatusInfo& infoOut);
    int weldDebugOperation(enum E_WELD_TEST typeIn,bool control);
    int setWeldCollisionCheck(bool isCheck);
    E_ROLLER_STATUS getRollerMechanismStatus();
    int setRollerMechanismConfig(RollerMechanismConfig configIn);
    int getRollerMechanismConfig(RollerMechanismConfig &configOut);
    E_LIFT_STATUS getLiftMechanismStatus();
    int setLiftMechanismConfig(LiftMechanismConfig configIn);
    int getLiftMechanismConfig(LiftMechanismConfig &configOut);

    bool getQuickStopFlag();
    int setWeldVirtualMode(bool isVirtualControlIn);
    bool getWeldIsVirtualStatus();

    int setRunningNumber_virtualLineControl(float numberIn);
    int setRunningNumber_robotArmControl(float numberIn);
    int getLaserCameraBufferMoveConfigParameter(struct BufferMoveConfig &paraOut);
    int setLaserCameraBufferMoveConfigParameter(struct BufferMoveConfig paraIn);
    int getLaserTrackConfigParameter(struct LaserTrackConfig &paraOut);
    int setLaserTrackConfigParameter(struct LaserTrackConfig paraIn);
    int getLaserCameraConfigParameter( struct LaserCameraConfigParameter &infoOut);
    int getLaserCameraStatus( struct LaserCameraStatusInfo &infoOut);
    int setLaserCameraConfigParameter( struct LaserCameraConfigParameter parameter);
    int reconnectLaserCamera();
    int setLaserCameraWork(bool isWork);
    int setLaserCameraJobId(int jobIdIn);
    int setLaserCameraShowLaser(bool isShow);

    int getWeldSystemInfo(struct WeldSystemInfo &weldSystemInfo);
    int changeWeldSystemInfo(struct WeldSystemInfo configIn);
    int getWeldCondition(std::vector<WeldCondition> &configListOut);
    int chanegWeldConditionConfig(struct WeldCondition &weldCondition);
    int getWeldProperty(std::vector<WeldProperty> &configListOut);
    int chanegWeldPropertyConfig(struct WeldProperty &weldProperty);
    int moveToNavgationPoint(MovingToNavagationParameter parameterIn,int &returnFlag);
    int addMonitorDi_fleet(bool isOr,QVector<int> diIndex,QVector<int> diValue);
    int addCircle(int idIn, std::vector<double> posIn, std::vector<double> centerIn,
                  std::vector<double> normalIn, double vel, int turnsIn, int velTypeIn);
    E_PROGRAM_LOOP_RESULT addProgramMoveCommand_hmi(vector<MoveParameter>& tmpCommandVectorIn);
    E_PROGRAM_LOOP_RESULT moveRobotArm_run(const QVector<int> &lineList,
                                   const QVector<RobotArmMoveParameter> &pathListParaIn, int isLastPointMove=0);
    E_PROGRAM_LOOP_RESULT moveMultiPoint_run(const QVector<int> &lineList,
                                   const QVector<LaserPathParameter> &laserPathListParaIn, int isLastPointMove=0);
    E_PROGRAM_LOOP_RESULT moveMagnetic_run(const MaganeticPathParameter paraIn);
    E_PROGRAM_LOOP_RESULT roller_run(const RollerParameter& paraIn);
    E_PROGRAM_LOOP_RESULT charging_run(const ChargeParameter& paraIn);
    E_PROGRAM_LOOP_RESULT liftMechanism_run(const LiftParameter& paraIn);
    int playMusic(QString musicFileName,int musicPlayTimes,int musicVolume);
    int playSystemMusic(QString nameIn, int musicPlayTimes);
    int playBarriorMusic(double barrierRatioIn);
    int playErrorMusic();
    int restoreNormalMusic();
    int getCmdStrList(QVector<QString> &listStrOut);
    int getMoveType();
    int setPlRegister(int palletNumber,PlRegStruct plReg,int &returnFlag);//存在线程安全问题
    int addCommand(UserCommandData commandIn);
    int getDpoint(std::string fileName,int pointIndex,DPoint &pointOut);
    int recordDpoint(std::string fileName,DPoint pointIn);
    int get_robot_running_program_files_info(std::vector<std::string> &fileNames,
                                             std::vector<int> &runningLines);
    int get_running_program_file_strings(int languageId, QString fileName,
                                                       QVector<QString> &programStrings);
    int get_running_program_file_strings_task(int languageId, QString fileName,
                                                       QVector<QString> &programStrings);
    int getProgramRunningInfo(int languageId, std::vector<string> &fileNames, std::vector<int> &runningLines, QVector<QVector<QString> > &programStrings);
    int setDefaultProgram(QString defaultProgramNameIn);
    bool isInRunningLoopStatus();
    int getDebugInfo(ProgramEngineDebugInfo& infoOut);
    int getDebugInfoList(std::vector<ProgramEngineDebugInfo>& infoListOut);
    int getTaskInfo(TaskManagerInfo &taskManagerInfo);

    EN_CONTROL_TYPE getRunModel();
    int getEngineStatue();
    int setRunModel(EN_CONTROL_TYPE runModelIn);
    int setRunModel_taskManager(EN_CONTROL_TYPE runModelIn, bool isManualLooseServoIn);
    int setMoveType(int moveTypeIn);
    int setMoveType_taskManager(int moveTypeIn);

    int getProgramEngineStatus();
    /**
     * @brief getCurrentRobotRunFile        获取当前机器人的运动相关文件
     * @param   runFile                     当前运行程序相关信息
     * @return
     */
     int getCurrentRobotRunFile(CurrentRunFile &runRobotFile);
     int getProgramSetRunFile(QString &fileName);

    /**
     * @brief parseFile2ProgramSet      读取程序文件并将程序文件解析成ｐｒｏｇｒａｍＳｅｔ
     * @param strFilePath               程序文件路径
     * @return
     */
    int initialProgramSetFromProgramFile(QString strFilePath, QString strFileNameIn);


    int readVersion(std::vector <ComponentVersion> &componentVersionList);

    /**
     * @brief updateControllerInfoLevel2 获取lv2的部分数据
     * @param updateDataLv2
     * @return  ok=1, 0=false
     */
    int updateControllerInfoLevel2( UpdateDataLv2  &updateDataLv2 );

    int updateControllerInfoLevel3( UpdateDataLv3  &updateDataLv3);

    /**
     * @brief internalCease     内部暂停
     * @return
     */
    int internalCease();
    int programEngineCease_noMotionThread();
    /**
     * @brief internalReset     内部停止,所有任务都会停
     * @return
     */
    int engineStop();

    int programSetReset();


//    /**
//     * @brief addTask           传递ｔａｓｋＭａｎａｇｅｒ的指针
//     * @param runTaskManager    ｔａｓｋＭａｎａｇｅｒ的指针
//     */
//    void addTask(TaskManager &runTaskManager);
    /**
     * @brief createTask        创建ＴａｓｋＭａｎａｇｅｒ
     */
    void initialRegister(int robotEngineStartType);//not used


    /**
     * @brief addBreakPoint     添加断点
     * @param fileName          程序名称
     * @param lineNum           行号
     * @return
     */
    int addBreakPoint(QString fileName,int lineNum);
    /**
     * @brief deleteBreakPoint  删除断点
     * @param fileName          程序名称
     * @param lineNum           行号
     * @return
     */
    int deleteBreakPoint(QString fileName,int lineNum);
    /**
     * @brief deleteAllBreakPoint   删除所有的断点
     * @return
     */
    int deleteAllBreakPoint();
    /**
     * @brief deleteSigleFileBreakPoint     删除一个文件的断点
     * @param fileName                      文件名
     * @return
     */
    int deleteSigleFileBreakPoint(QString fileName);
    /**
     * @brief clearMessage                  清除消息
     * @param engineMsg                     清除引擎消息
     * @return
     */
    int clearMessage(Message engineMsg);//not use
    /**********************************************************************************************
     * hmi发送过来的为程序文件，直接通过ｆｔｐ映射，对文件进行操作，ｈｍｉ需要添加将程序指令字符串写入文件的操作
     *
     * *******************************************************************************************/

    /**
     * @brief addMessage                添加消息
     * @param engineMessage             消息对象
     */
    void addMessage(Message engineMessage);


    /**
     * @brief addRegRsrData            传递RegData的指针
     * @param mainRegData           RegData的指针
     * @param rsrInfo                      RsrInfo的指针
     * @return
     */
    void addRegRsrData(RegData &mainRegData,RsrInfo &tmpRsrInfo);

    /**
     * @brief updateUserCoordinateData          更新用户坐标系的数据
     * @param userCoordinateList                用户坐标系数据
     * @return
     */
    int updateUserCoordinateData(QVector<UserCoordinateInfo> userCoordinateList);
    /**
     * @brief updateToolCoordinateData          更新工具坐标系的数据
     * @param toolCoordinateList                工具坐标系数据
     * @return
     */
    int updateToolCoordinateData(QVector<ToolCoordinateInfo> toolCoordinateList);

//    void runChildProgram();

    void initialParameter(int moveTypeIn, EN_CONTROL_TYPE runModelIn);


    void childTaskOpenFile(QString runFileName,int childTaskIndex);
    void childTaskRun(int childTaskIndex);
    int setRunModel_forChildTask(int runModelIn);
    int setMoveType_forChildTask(int moveTypeIn);
    int clearAllMsg( );
    int clearAllMsg_self( );

 //---------------------------------------------
private slots:
    /**
     * @brief slot_runProgram2 ,为解决，runProgram()函数重入问题
     */
    int programEngineTaskLoop(int taskIndexIn);


private:
    bool isRunningBreak();
    E_PROGRAM_LOOP_RESULT processOneProgram(int programIndex);

//---------------------------------------------
public slots:
    int setRunModel_slot(int runModelIn);
    int setMoveType_slot(int moveTypeIn);


    /**
     * @brief slot_runCommand 　让指定线程打开文件
     * @param th　　指定线程
     * @param fileName　文件
     *
     */
    void childTaskOpenFile_slot(QString fileName, int childTaskIndex);
    /**
     * @brief runProgram        运行程序　　　循环调用　　间隔周期为１０ｍｓ
     * @return
     */
    int runProgram();
    /**
     * @brief openFile              打开文件 , 这里面调用 parseFile2ProgramSet , 继而调用 readProgram
     * @param strFileName           文件名称
     * @return
     */
    int openFile(QString strFileName);

    int openFile_clearPrivious(QString strFileName);
    int openDefaultFile_clearPrivious();

    /**
     * @brief readProgram           读取文件
     * @param strFilePath           文件路径
     * @return                      根据返回值类型判断是否有中断发生　　１表示有中断发生　　０标示没有
     */
    int readOneProgramFile(QString strFilePath);


//    int engineThreadDestory();

    /**
     * @brief ceaseProgram      外部指令调用　暂停　暴露接口为ＣｌｉｅｎｔＴｈｒｅａｄ在调用者的线程中运行
     * @return
     */
    int ceaseProgram();
    int quickStop();

    int setEngineStatus_fleet(STOP_COMMAND_TYPE statusIn);
    int setEngineStatusRun();
    int setEngineStatusStop();
    /**
     * @brief resetProgram      外部调用指令　　停止　暴露接口为ＣｌｉｅｎｔＴｈｒｅａｄ在调用者的线程中运行
     * @return
     */
    int resetEngineAll();

    int resetAllProgramSet();
    int restoreDefaultPogramSet();

    //for task to use
    int setTaskRunState();
    int setTaskCeaseState();
    int setTaskStopState();

//    int resetTaskManager();
    /**
     * @brief releaseHoldOn
     * @return
     */
    int releaseHoldOn();
    /***********************************
     * 日期：2017年2月20号
     * 修改人：steven
     * 修改内容：添加发生报警级别的消息后将运动模式切换为T1模式
     * *********************************/
    /**
     * @brief setErrorMsgModel      设置报警级别的运行模式T1
     * @return
     */
    int setErrorMsgModel();
    /**
     * @brief setStartLine  设置当前程序从那一行开始运行
     * @param lineNum       行号
     * @return
     */
    int setStartLine(int lineNum);



    //--------------------------------------------
signals:
    void openFile_signal(QString runFileName);
    void signal_runProgram();
    void signal_runProgram_main();

    void runNewTask_signal(int taskIndexIn);
    void childTaskOpenFile_signal(QString runFileName,int childTaskIndex);
    void childTaskRun_signal(int childTaskIndex);
    void engineThreadDestory_signal();

    int setRunModel_signal(int runModelIn);
    int setMoveType_signal(int moveTypeIn);



//-------------------------------------------------------------------------------------------------------
friend class IfInstructionLogic;
friend class AbortInstructionLogic;
friend class CallInstructionLogic;
friend class CoordinateInstructionLogic;
friend class EndInstructionLogic;
friend class ErrorInstructionLogic;
friend class ForInstructionLogic;
friend class GoToInstructionLogic;
friend class GripperInstructionLogic;
friend class IoInstructionLogic;
friend class JumpInstructionLogic;
friend class LabelInstructionLogic;
friend class MessageInstructionLogic;
friend class MotionInstructionLogic;
friend class OverrideInstructionLogic;
friend class PalInstructionLogic;
friend class PauseInstructionLogic;
friend class RegInstructionLogic;
friend class RsrInstructionLogic;
friend class RunInstructionLogic;
friend class SelectInstructionLogic;
friend class TimerInstructionLogic;
friend class UalmInstructionLogic;
friend class WaitInstructionLogic;
friend class TaskManager;
friend class MoveMagneticInstructionLogic;
friend class MoveFreeInstructionLogic;
friend class MusicInstructionLogic;
friend class ChargingInstructionLogic;
friend class LiftMechanismInstructionLogic;
friend class TcpStartInstructionLogic;
friend class TcpReadInstructionLogic;
friend class TcpWriteInstructionLogic;
friend class LoadMapInstructionLogic;
friend class CheckBatteryInstructionLogic;
friend class SetOdomInstructionLogic;
friend class WaitCommandInstructionLogic;
friend class RobotMoveInstructionLogic;
friend class RollerInstructionLogic;
friend class TcpManager;
friend class ProgramLanguageTranslate;
friend class ModbusStartInstructionLogic;
friend class ModbusReadInstructionLogic;
friend class ModbusWriteInstructionLogic;
friend class VisionRunLogic;
friend class TrackStartLogic;
//拓展新指令Fundation增加代码20191122hualei
friend class WeldStartInstructionLogic;
friend class WeldEndInstructionLogic;
friend class WeaveInstructionLogic;
friend class WeaveEndInstructionLogic;
friend class TrackWeldTastInstructionLogic;
friend class TrackWeldEndInstructionLogic;
friend class WatchDIInstructionLogic;
friend class LaserCameraInstructionLogic;
private:
    //-------------给instructionLogic类使用-----------------
    int weldWorkingMonitor();
    int loadPointAndPalInfo(int index);
    int updateProgramSetRunInformation(int programIndex);
    float getPcFlagValue();
    int setPcFlagValue(float valueIn);
    bool get_mamual_run_flag();
    bool set_mamual_run_flag(bool value);

    bool isMainThreadTrue();
//    QString getCurrentFile();
//    int setProgramCountNum(int num);
//    int getProgramSetSize();
    float getRunningLineFloat();
    int setRunningLineFloat(float lineIn);

    QString getCurrentProgramName();

    int setMotionStage(E_PROGRAM_MOTION_STAGE stage);
    bool getSetRunNumFlag();
    bool writeSetRunNumFlag(bool value);
    int setMotionInstructionAdded(int number);
    int setCurrentProgramName(QString fileName);
    //------------------------------------------------


    /**
     * @brief startMotion           获取motion指令后的操作
     * @param programNum            正在运行的program的Number
     * @param motionInstruction     MotionInstruction对象
     * @return                      返回１表示运行到了最后一行
     */
    E_PROGRAM_LOOP_RESULT startMotion(int programNum, int startLine);
    E_PROGRAM_LOOP_RESULT startAxisMove(int programNum, int startLine);
    E_PROGRAM_LOOP_RESULT startFetchWeldPoint(int programNum, int startLine);
    E_PROGRAM_LOOP_RESULT startLaserCameraControl(int programNum, int startLine);
    E_PROGRAM_LOOP_RESULT startLaserCameraTrack(int programNum, int startLine);

    /**
     * @brief startWait             获取wait指令后的操作
     * @param programNum            正在运行的program的Number
     * @param waitInstruct          waitInstruction对象
     * @return                      返回１表示运行到了最后一行
     */
    E_PROGRAM_LOOP_RESULT startWait(int programNum,waitInstruction waitInstruct);

    E_PROGRAM_LOOP_RESULT startMoveMaganetic(int programNum, int startLine);

    E_PROGRAM_LOOP_RESULT startMoveFree(int programNum, int startLine);



//    /**
//     * @brief startGoto             获取goto指令后的操作,没有该指令
//     * @param programNum            正在运行的program的Number
//     * @return                      返回１表示运行到了最后一行
//     */
//    E_PROGRAM_LOOP_RESULT startGoto(int programNum);
    /**
     * @brief startJump             获取jump指令后的操作
     * @param programNum            正在运行的program的Number
     * @param jumpNum               jump到哪一个ｌａｂｅｌ的标号
     * @return                      返回１表示运行到了最后一行
     */
    E_PROGRAM_LOOP_RESULT startJump(int programNum, QString jumpLabelIn);
    /**
     * @brief startReg              获取reg指令后的操作
     * @param programNum            正在运行的program的Number
     * @param registerInstruct      RegisterInstruction对象
     * @return                      返回１表示运行到了最后一行
     */
    E_PROGRAM_LOOP_RESULT startReg(int programNum,RegisterInstruction registerInstruct);
    E_PROGRAM_LOOP_RESULT startPrReg(int programNum,const PrRegisterInstruction &prRegisterInstruction);
    E_PROGRAM_LOOP_RESULT startPlReg(int programNum,const PlRegisterInstruction &plRegisterInstruction);
    /**
     * @brief startIo               获取IO指令后的操作
     * @param programNum            正在运行的program的Number
     * @param ioInstruct            IoInstruction对象
     * @return                      返回１表示运行到了最后一行
     */
    E_PROGRAM_LOOP_RESULT startIo(int programNum,IoInstruction ioInstruct);
    /**
     * @brief startLabel           　获取label标签指令后的操作
     * @param programNum            正在运行的program的Number
     * @return                      返回１表示运行到了最后一行
     */
    E_PROGRAM_LOOP_RESULT startLabel(int programNum);
    /**
     * @brief startRun              获取run指令后的操作
     * @param programNum            正在运行的program的Number
     * @param runProgramName        ｒｕｎ程序名称
     * @return                      返回１表示运行到了最后一行
     */
    E_PROGRAM_LOOP_RESULT startRun(int programNum,QString runProgramName);
    /**
     * @brief startCall             获取call指令后的操作
     * @param programNum            正在运行的program的Number
     * @param callProgramName       被ｃａｌｌ的程序名称
     * @return                      返回１表示运行到了最后一行
     */
    E_PROGRAM_LOOP_RESULT startCall(int programNum,QString callProgramName);
    /**
     * @brief startSelect           获取select指令后的操作
     * @param programNum            正在运行的program的Number
     * @param selectInstruction     SelectInstruction对象
     * @return                      返回１表示运行到了最后一行
     */
    E_PROGRAM_LOOP_RESULT startSelect(int programNum,SelectInstruction selectInstruction);
    /**
     * @brief startFor              获取for指令后的操作
     * @param programNum            正在运行的program的Number
     * @param forInstruct           ForInstruction对象
     * @return                      返回１表示运行到了最后一行
     */
    E_PROGRAM_LOOP_RESULT startFor(int programNum,ForInstruction forInstruct);
    /**
     * @brief startEndfor           获取endfor指令后的操作
     * @param programNum            正在运行的program的Number
     * @return                      返回１表示运行到了最后一行
     */
    E_PROGRAM_LOOP_RESULT startEndfor(int programNum);
    /**
     * @brief startPal              码垛指令Ｂ、Ｂｘ、Ｅ、Ｅｘ、Ｅｎｄ
     * @param programNum            程序号码
     * @return
     */
    E_PROGRAM_LOOP_RESULT startPal(int programNum,PalInstruction palInstruct);
    /**
     * @brief caseAnd               获取select指令的And指令后的操作
     * @param programNum            正在运行的program的Number
     * @param andIfInstruction      IfInstruction对象
     * @return                      返回１表示运行到了最后一行
     */
    E_PROGRAM_LOOP_RESULT caseAnd(int programNum,IfInstruction andIfInstruction);
    /**
     * @brief caseOr                获取select指令后的or指令后的操作
     * @param programNum            正在运行的program的Number
     * @param orIfInstruction       IfInstruction对象
     * @return                      返回１表示运行到了最后一行
     */
    E_PROGRAM_LOOP_RESULT caseOr(int programNum,IfInstruction orIfInstruction);
    /**
     * @brief caseNeither           获取select指令后既不是And也不是or指令的操作
     * @param programNum            正在运行的program的Number
     * @param nIfInstruction        IfInstruction对象
     * @return                      返回１表示运行到了最后一行
     */
    E_PROGRAM_LOOP_RESULT caseNeither(int programNum,IfInstruction nIfInstruction);
    /**
        * @brief startCoorDinate   获取坐标系指令后的操作
        * @param programNum        正在运行的program的Number
        * @param coorInstruct      CoorDinateInstruction对象
        */
    E_PROGRAM_LOOP_RESULT startCoorDinate(int programNum,CoorDinateInstruction coorInstruct);
    /**
     * @brief startErr      错误指令
     * @param programNum    程序号
     */
    E_PROGRAM_LOOP_RESULT startErr(int programNum);
//    /**
//     * @brief startMotionSkip
//     * @param programNum
//     * @param motionInstruct
//     * @return
//     */
//    E_PROGRAM_LOOP_RESULT startMotionSkip(int programNum,MotionInstruction motionInstruct);
    /**
     * @brief startPause
     * @param programNum
     * @param pauseInstruct
     * @return
     */
    E_PROGRAM_LOOP_RESULT startPause(int programNum,PauseInstruction pauseInstruct);
    /**
     * @brief startAbort
     * @param programNum
     * @param abortInstruct
     * @return
     */
    E_PROGRAM_LOOP_RESULT startAbort(int programNum,AbortInstruction abortInstruct);
    /**
     * @brief startEnd
     * @param programNum
     * @param endInstruct
     * @return
     */
    E_PROGRAM_LOOP_RESULT startEnd(int programNum,EndInstruction endInstruct);
    /**
     * @brief startUalm
     * @param programNum
     * @param ualmInstruct
     * @return
     */
    E_PROGRAM_LOOP_RESULT startUalm(int programNum,UalmInstruction ualmInstruct);
    /**
     * @brief startMessage
     * @param programNum
     * @param messageInstruct
     * @return
     */
    E_PROGRAM_LOOP_RESULT startMessage(int programNum,MessageInstruction messageInstruct);
    /**
     * @brief startOverride
     * @param programNum
     * @param overrideInstruct
     * @return
     */
    E_PROGRAM_LOOP_RESULT startOverride(int programNum,OverrideInstruction overrideInstruct);
    /**
     * @brief startTimerCmd
     * @param programNum
     * @param timerInstruct
     * @return
     */
    E_PROGRAM_LOOP_RESULT startTimerCmd(int programNum,TimerInstruction timerInstruct);
    /**
     * @brief startRsr
     * @param programNum
     * @param rsrInstruct
     * @return
     */
    E_PROGRAM_LOOP_RESULT startRsr(int programNum,RsrInstruction rsrInstruct);

    /***************************
     * 日期：2017－7－24
     * 修改人：steven
     * 添加内容：手抓功能
     * *************************/
    E_PROGRAM_LOOP_RESULT startGripper(int programNum,GripperInstruction gripperInstruct);


    /**
     * @brief startAnnotation
     * @param programNum
     * @return
     */
    E_PROGRAM_LOOP_RESULT startAnnotation(int programNum);
    /**
     * @brief parseCmd
     * @param programNum    程序号
     * @return
     */
    E_PROGRAM_LOOP_RESULT processCurrentRunningInstructionOneTime(int programIndex, INSTRUCTION_TYPE programInstructionTypeIn);

    /**
     * @brief isTheLastInstruction           程序指令运行一行的处理逻辑以及根据运动类型处理
     * @param programNum        程序标号
     * @return                  １标示运行到了最后一行
     */
    E_PROGRAM_LOOP_RESULT isTheLastInstruction(int programNum);


    /*************************************************************
     * 修改人:          hualei
     * 修改时间:  (1) 2018-09-17
     *            (2) 2018-09-30
     *
     * 修改说明:  (1) 添加 MUSIC 音乐指令实现
     *            (2) 添加 CHARGING 充电指令和 LIFT 升降机构指令实现接口
     *
     * **********************************************************/
    /**
     * @brief startMusic                开始执行音乐指令
     * @param programNumIn              程序编号
     * @param startLine                 开始执行指令行号
     * @return
     */
    E_PROGRAM_LOOP_RESULT startMusic(int programNumIn, int startLine);

    /**
     * @brief startCharging             开始执行充电指令
     * @param programNumIn              程序编号
     * @param startLine                 开始执行指令行号
     * @return
     */
    E_PROGRAM_LOOP_RESULT startCharging(int programNumIn, int startLine);

    /**
     * @brief startLiftMechanism        开始执行升降机构指令
     * @param programNumIn              程序编号
     * @param startLine                 开始指令指令行号
     * @return
     */
    E_PROGRAM_LOOP_RESULT startLiftMechanism(int programNumIn, int startLine);

    /**
     * @brief startTcpStart             开始执行TCP_START 以太网起始指令
     * @param programNumIn              程序编号
     * @param startLine                 开始指令指令行号
     * @return 
     */
    E_PROGRAM_LOOP_RESULT startTcpStart(int programNumIn, int startLine);

    /**
     * @brief startTcpRead              开始执行 TCP_READ 以太网读取指令
     * @param programNumIn              程序编号
     * @param startLine                 开始指令指令行号
     * @return 
     */
    E_PROGRAM_LOOP_RESULT startTcpRead(int programNumIn, int startLine);
    
    /**
     * @brief startTcpWrite             开始执行 TCP_WRITE 以太网写入指令
     * @param programNumIn              程序编号
     * @param startLine                 开始执行指令行号
     * @return 
     */
    E_PROGRAM_LOOP_RESULT startTcpWrite(int programNumIn, int startLine);

    /**
     * @brief startLoadMap              开始执行 LOAD_MAP 加载地图指令
     * @param programNumIn              程序编号
     * @param startLine                 开始执行指令行号
     * @return
     */
    E_PROGRAM_LOOP_RESULT startLoadMap(int programNumIn, int startLine);


 
    /**
     * @brief startCheckBattery         开始执行 CHECK BATTERY 指令
     * @param programNumIn              程序编号
     * @param startLine                 开始执行指令行号
     * @return
     */
    E_PROGRAM_LOOP_RESULT startCheckBattery(int programNumIn, int startLine);
    /**
     * @brief startCheckBattery         开始执行 WAIT_COMMAND 指令
     * @param programNumIn              程序编号
     * @param startLine                 开始执行指令行号
     * @return
     */
    E_PROGRAM_LOOP_RESULT startWaitCommand(int programNumIn, int startLine);
     /**
         * @brief startSetOdom              SET_ODOM 开始执行重置里程计指令
         * @param programNumIn              程序编号
         * @param startLine                 开始执行指令行号
         * @return
         */
    E_PROGRAM_LOOP_RESULT startSetOdom(int programNumIn, int startLine);


    E_PROGRAM_LOOP_RESULT startRobotMove(int programNumIn, int startLine);


    E_PROGRAM_LOOP_RESULT startRoller(int programNumIn, int startLine);

    E_PROGRAM_LOOP_RESULT startModbusStart(int programNumIn, int startLine);
    E_PROGRAM_LOOP_RESULT startModbusRead(int programNumIn, int startLine);
    E_PROGRAM_LOOP_RESULT startModbusWrite(int programNumIn, int startLine);

    E_PROGRAM_LOOP_RESULT startVisionRun(int programNumIn, int startLine);
    E_PROGRAM_LOOP_RESULT startVisionClearData(int programNumIn, int startLine);
    E_PROGRAM_LOOP_RESULT startVisionGetData(int programNumIn, int startLine);
    E_PROGRAM_LOOP_RESULT startVisionTrigger(int programNumIn, int startLine);

    E_PROGRAM_LOOP_RESULT startTrackStart(int programNumIn, int startLine);
    E_PROGRAM_LOOP_RESULT startTrackEnd(int programNumIn, int startLine);
    E_PROGRAM_LOOP_RESULT startTrackGetData(int programNumIn, int startLine);
    //拓展新指令Fundation增加代码20191122hualei
    E_PROGRAM_LOOP_RESULT startWeldStart(int programNumIn, int startLine);
    E_PROGRAM_LOOP_RESULT startWeldEnd(int programNumIn, int startLine);
    E_PROGRAM_LOOP_RESULT startWeave(int programNumIn, int startLine);
    E_PROGRAM_LOOP_RESULT startWeaveEnd(int programNumIn, int startLine);
    E_PROGRAM_LOOP_RESULT startTrackWeldTast(int programNumIn, int startLine);
    E_PROGRAM_LOOP_RESULT startTrackWeldEnd(int programNumIn, int startLine);
    E_PROGRAM_LOOP_RESULT startWatchDI(int programNumIn, int startLine);


    /**
     * @brief parsePLData           解析PL指令，最后返回【i、j、k】
     * @return                      返回【i、j、k】
     */
    QVector <int> parsePLData(int programNum);
    /**
     * @brief parsePRData           解析PR指令，最后返回PR的值
     * @return
     */
//    RegisterPrIns parsePRData();
    PointPro parsePRData(int programNum);

    float parseRegisterData(int programNum);



    /**
     * @brief realTimeSleep        睡眠函数
     * @param microsecond          睡眠时间 ：单位ｕｓ
     */
    void realTimeSleep(long long umicoroSecond);

    /**
     * @brief pretreatMotion    预处理运动指令
     * @param programNum        程序标号
     * @return
     */
    int pretreatMotion();
    /**
     * @brief processMoveType   处理不同的运动类型的指令
     * @param programNum        程序标号
     * @return
     */
    int calculateNextLineToRun(int programNum);

    /**
     * @brief getSetMotionBlock
     * @param startLineNum
     * @return
     */
    int getSetMotionBlock(int startLineNum);//not used


    /**
     * @brief processWaitTimeOut
     * @param programNum
     * @param waitInstruct
     */
    void processWaitTimeOut(int programNum,waitInstruction waitInstruct);

    bool countWaitTime(float waitTime);

    void cmdError(int programNum);

    int updateProgramSetRegister();//尽量废弃该函数，直接传递RegData *regData

//    int updateTimerReg();

    double countIntervalTime(timeval startTimeVal,timeval endTimeVal);



    /**
     * @brief addMsg  , 添加消息反馈
     * @param messageLevel
     * @param componentName
     * @param messageType
     * @param messageCode
     * @param robotId
     * @param parameter1
     * @param parameter2
     * @param parameter3
     * @param parameter4
     */
    void addMsg( int messageLevel,
                 std::string componentName,
                 std::string messageType,
                 int messageCode,
                 int robotId,
                 int parameter1 = 0,
                 int parameter2 = 0,
                 int parameter3 = 0,
                 int parameter4 = 0,
                 QString message= "");


    /**
   * @brief lock //加锁
     * @return  ok=true
   */
    bool lock(){
        pthread_mutex_lock(&programMutex) ;
        return true;
    }

    /**
   * @brief unlock //解锁
   */
    void unlock(){
        pthread_mutex_unlock(&programMutex) ;
    }

    /**
     * @brief trylock //加锁
     * @return  ok=true
     */
    bool trylock(){
        if(  0==pthread_mutex_trylock(&programMutex) )
        {
            return true;
        }else{
            return false;
        }
    }

//    bool threadStop();



    int initialInstruction();
    int deleteInstruction();

    void* threadRun(void *);
    static void* threadTask( void* classPtr );
    void createThread();

//--------------------------------------------------------------------------------------------
public:
    /**
     * @brief regData           寄存器数据
     */
    RegData *regData;

private:

    /**
     * @brief programLanguageTranslate      程序语言翻译类
     */
    ProgramLanguageTranslate *programLanguageTranslate;

    /**
     * @brief cmdStrList    命令指令
     */
    QVector <QString> cmdStrList;
    QMutex cmdStrListMutex;

    /**
     * @brief programNum    程序总个数
     */
    int programCountSize;
    /**
     * @brief pCount        当前运行到哪一行
     * 改为 foat , 0.2=算法已取点, 0.5=正在运行，0.9=(已经到目标位置),  ,下一行+0.2(避免精度丢失,不用0.1)
     */
    volatile  float runningLineFloat;
    /**
     * @brief commandType   命令类型
     */
    INSTRUCTION_TYPE programInstructionType;
    /**
     * @brief currentProgramName    当前程序的名字
     */
    QString currentProgramName;


    /**
     * @brief taskManager       多任务管理组件,暂时不支持任务嵌套
     */
    TaskManager *taskManager;
    int taskIndex;
    /**
     * @brief pointData         点位数据组件,hualei 暂时没用。
     */
    PointData *pointData;

    /**
     * @brief programMcController       算法线程指针
     */
    McControllerThread *programMcController;

    /**
     * @brief ioController io控制指针
     */
    RobotIo* ioController;
    ProgramUpdateDataList programUpdateDataList;
    /**
     * @brief robotId   机器人号码
     */
    int robotId;
    /**
     * @brief startType     启动方式　０代表冷启动　　１代表热启动
     */
    int startType;
    /**
     * @brief runModel  运行类型    0 T1手动\1 T2手动\2 自动\3 EX (HMI 连续单步)
     */
    volatile EN_CONTROL_TYPE runModel;
    /**
     * @brief moveType  0单步运行　　１连续运行
     */
    volatile int moveType;
    /**
      * @brief mamual_run_flag 运行标志（手动T1,T2时判别是否运行）
      */
     bool oneStepEnableFlag;
    /**
     * @brief engineStatus      引擎状态
     */
    volatile STOP_COMMAND_TYPE engineStatus;

    int loopTimeCount;

    /**
     * @brief motionIsFinished  未做平滑处理的运动指令的完成标志
     */
    int motionIsFinished;
    /**
     * @brief debugEnable       调试开关
     */
    int debugEnable;

    /******************************
     * 日期：2017－3－6
     * 添加人：ｓｔｅｖｅｎ
     * 添加内容：ｒｓｒ信息
     * *****************************/
    RsrInfo *rsrInfo;
    /**
     * @brief ProgramSet        属性property暴露，给算法调用
     */
    ProgramSet *programSet;//一个任务一个程序集

    /**
     * @brief getPointProList   保存普通点到ｐｏｉｎｔＤａｔａ组件的操作, hualei 导致无法call的时候不从新加载
     */
    QVector <PointPro> *currentPointProList;

    QMap <int, DPoint> currentVehicleDPointList;
    /**
     * @brief palletStackInfo    保存码垛点到ｐｏｉｎｔＤａｔａ组件的操作
     */
//    QVector <StackInfo> currentPalletStackInfo;
    /****************************************************
     * 日期：2017－3－2２
     * 添加人：ｓｔｅｖｅｎ
     * 添加内容：多任务下存储普通点和码垛点的容器
     * ****************************************************/
    /**
     * @brief allPointProList       多任务下的所有的普通点信息
     */
    QVector <QVector <PointPro> > *allPointProList;
    /**
     * @brief allVehicleDPointList 多任务下的所有的DP点信息
     */

    QVector <QMap <int, DPoint> > allVehicleDPointList;
    /**
     * @brief allStackInfoList      多任务下的所有的码垛点的信息,存在线程安全问题
     */
//    QVector <QVector <StackInfo> > allStackInfoList;
    /**
     * @brief regPlList         对接RegData组件的pl寄存器接口
     */
    QVector <PlRegStruct> regPlList;

    int programFileVersionInfo;//程序版本号

    //---------------------------------------------

private:
    QString defaultProgramName;
    volatile bool isInRunningLoop;
    pthread_mutex_t programMutex;//线程互斥锁
    pthread_cond_t programCond;//线程同步信号
    pthread_mutexattr_t programAttr;

    pthread_mutex_t engineStatusMutex;//no use
    pthread_mutexattr_t engineStatusMutexAttr;//no use

    bool isMainThread;//是否是主ProgramEngine

    QThread *currentThread;


     float pcFlagValue;

     bool setRunNumFlag;

     struct timeval openFileStartTime,openFileEndTime,readFileStartTime,readFileEndTime,processStartTime,processEndTime;

//     QString openFileName;
     ComponentVersion versionInfo;

     bool isProgramEngineInitialOk;
     ProgramEngineDebugInfo engineDebugInfo;

     IfInstructionLogic *ifInstructionLogic;
     AbortInstructionLogic *abortInstructionLogic;
     CallInstructionLogic *callInstructionLogic;
     CoordinateInstructionLogic *coordinateInstructionLogic;
     EndInstructionLogic *endInstructionLogic;
     ErrorInstructionLogic *errorInstructionLogic;
     ForInstructionLogic *forInstructionLogic;
     GoToInstructionLogic *goToInstructionLogic;
     GripperInstructionLogic *gripperInstructionLogic;
     IoInstructionLogic *ioInstructionLogic;
     JumpInstructionLogic *jumpInstructionLogic;
     LabelInstructionLogic *labelInstructionLogic;
     MessageInstructionLogic *messageInstructionLogic;
     MotionInstructionLogic *motionInstructionLogic;
     OverrideInstructionLogic *overrideInstructionLogic;
     PalInstructionLogic *palInstructionLogic;
     PauseInstructionLogic *pauseInstructionLogic;
     RegInstructionLogic *regInstructionLogic;
     RsrInstructionLogic *rsrInstructionLogic;
     RunInstructionLogic *runInstructionLogic;
     SelectInstructionLogic *selectInstructionLogic;
     TimerInstructionLogic *timerInstructionLogic;
     UalmInstructionLogic *ualmInstructionLogic;
     WaitInstructionLogic *waitInstructionLogic;
     MoveMagneticInstructionLogic *moveMagneticInstructionLogic;
     MoveFreeInstructionLogic *moveFreeInstructionLogic;
     MusicInstructionLogic *musicInstructionLogic;

     ChargingInstructionLogic *chargingInstructionLogic;
     LiftMechanismInstructionLogic *liftMechanismInstructionLogic;
     
     TcpStartInstructionLogic *tcpStartInstructionLogic;
     TcpReadInstructionLogic *tcpReadInstructionLogic;
     TcpWriteInstructionLogic *tcpWriteInstructionLogic;

     LoadMapInstructionLogic *loadMapInstructionLogic;
     SetOdomInstructionLogic *setOdomInstructionLogic;

     CheckBatteryInstructionLogic *checkBatteryInstructionLogic;
     WaitCommandInstructionLogic *waitCommandInstructionLogic;

     RobotMoveInstructionLogic *robotMoveInstructionLogic;

     RollerInstructionLogic *rollerInstructionLogic;
     ModbusStartInstructionLogic *modbusStartInstructionLogic;
     ModbusReadInstructionLogic *modbusReadInstructionLogic;
     ModbusWriteInstructionLogic *modbusWriteInstructionLogic;

     VisionRunLogic *visionRunLogic;
     TrackStartLogic *trackStartLogic;

     //拓展新指令Fundation增加代码20191122hualei
//     WeldEndInstructionLogic *weldEndLogic;
     WeldStartInstructionLogic *weldStartLogic;
     WeaveInstructionLogic *weaveLogic;
//     WeaveEndInstructionLogic *weaveEndLogic;
     TrackWeldTastInstructionLogic *trackWeldTastLogic;
     TrackWeldEndInstructionLogic *trackWeldEndLogic;
     WatchDIInstructionLogic *watchDILogic;
     LaserCameraInstructionLogic *laserCameraInstructionLogic;
     LaserCameraTrajServer *lasercameraTrajServer;

     LaserCameraAdapter *laserCameraAdapter;

     QMutex fileMutex;//文件锁，防止打开文件和运行程序时序出错误。

     bool isErrorOccured;//是否发生错误。
     bool quickStopFlag;
     
};

#endif // PROGRAMENGINE_H
